package com.proton.carepatchtemp.activity;

import android.app.ProgressDialog;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.content.ContextCompat;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.TextView;

import com.apkfuns.logutils.LogUtils;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.google.gson.reflect.TypeToken;
import com.proton.carepatchtemp.R;
import com.proton.carepatchtemp.base.BaseActivity;
import com.proton.carepatchtemp.constant.Config;
import com.proton.carepatchtemp.constant.Extras;
import com.proton.carepatchtemp.database.table.Report;
import com.proton.carepatchtemp.ui.ChartView.DayAxisValueFormatter;
import com.proton.carepatchtemp.ui.ChartView.MyAxisValueFormatter;
import com.proton.carepatchtemp.ui.ChartView.XYMarkerView;
import com.proton.carepatchtemp.utils.FileUtils;
import com.proton.carepatchtemp.utils.FormatUtils;
import com.proton.carepatchtemp.utils.JSONUtils;
import com.proton.carepatchtemp.utils.NumUtils;
import com.proton.carepatchtemp.utils.SpUtils;
import com.proton.carepatchtemp.utils.TastyUtils;
import com.proton.carepatchtemp.utils.eventbus.MainEvent;
import com.sdsmdg.tastytoast.TastyToast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ReportBigChartActivity extends BaseActivity implements OnChartValueSelectedListener {
    ArrayList<Entry> yVals1 = new ArrayList<Entry>();
    ProgressDialog mProgressDialog;
    private Report mReport;
    private ImageButton mBtnBack;
    private LineChart mBcReportChart;
    private TextView mTvMaxTemp;
    private YAxis mLeftAxis;
    private MyHandler mMyHandler;
    private float maxTemp;
    private DayAxisValueFormatter mXAxisFormatter;
    /**
     * ℃
     */
    private TextView mTvReportBigUnit;

    @Override
    public void dealEvent(MainEvent event) {

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_report_big_chart);
        mProgressDialog = new ProgressDialog(ReportBigChartActivity.this);
        mProgressDialog.show();
        if (null == getIntent().getExtras()) {
            TastyUtils.makeTextShort(R.string.get_rpt_info_failed, TastyToast.ERROR);
        } else {
            mReport = (Report) getIntent().getExtras().getSerializable(Extras.REPORT);
            if (null == mReport) {
                TastyUtils.makeTextShort(R.string.get_rpt_info_failed, TastyToast.ERROR);
                finish();
            }
        }

        mMyHandler = new MyHandler(ReportBigChartActivity.this);

        initView();
        setListener();
        initChart();
        setData();
    }

    @Override
    protected void setListener() {
        mBtnBack.setOnClickListener(v -> {
            finish();
        });
    }

    @Override
    public void onEventMainThread(MainEvent event) {

    }

    private void initView() {
        mBtnBack = findViewById(R.id.btn_back);
        mBcReportChart = findViewById(R.id.bc_report_chart);
        mTvMaxTemp = findViewById(R.id.tv_max_temp);
        mTvReportBigUnit = findViewById(R.id.tv_report_big_unit);
    }

    private void initChart() {
        mBcReportChart.setOnChartValueSelectedListener(this);

        mBcReportChart.getDescription().setEnabled(false);

//        mLineChart.setDrawBarShadow(false);
        //  禁止绘制点击柱状图后的标签
        mBcReportChart.setDrawMarkers(true);

        // if more than 60 entries are displayed in the chart, no values will be
        // drawn
//        mLineChart.setMaxVisibleValueCount(60);

        // scaling can now only be done on x- and y-axis separately
        mBcReportChart.setPinchZoom(true);

        mBcReportChart.setScaleYEnabled(false);

        mBcReportChart.setScaleXEnabled(false);

        mBcReportChart.setDrawGridBackground(false);

        mBcReportChart.setDoubleTapToZoomEnabled(false);

        mBcReportChart.setVisibleYRange(34, 42, YAxis.AxisDependency.LEFT);

        mBcReportChart.setDrawBorders(false);

        mBcReportChart.animateX(1000);

        mBcReportChart.setNoDataText(getString(R.string.have_no_data));

        mXAxisFormatter = new DayAxisValueFormatter(mBcReportChart);
        mXAxisFormatter.setStartTime(mReport.getStarttime());

        XAxis xAxis = mBcReportChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setValueFormatter(mXAxisFormatter);
        xAxis.enableGridDashedLine(10f, 10f, 0f);

        IAxisValueFormatter custom = new MyAxisValueFormatter();

        mLeftAxis = mBcReportChart.getAxisLeft();
        if (1 == SpUtils.getInt(Extras.TEMP_UNIT, Config.TEMP_UNIT_DEFAULT)) {
            mTvReportBigUnit.setText(R.string.C);
            mLeftAxis.setAxisMinimum(30.0f);
            mLeftAxis.setAxisMaximum(42.0f);
        } else {
            mTvReportBigUnit.setText(R.string.F);
            mLeftAxis.setAxisMinimum(86F);
            mLeftAxis.setAxisMaximum(107.6F);
        }
        mLeftAxis.setValueFormatter(custom);
        mLeftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
        mLeftAxis.setSpaceTop(15f);
        mLeftAxis.enableGridDashedLine(10f, 10f, 0f);

        YAxis rightAxis = mBcReportChart.getAxisRight();
        rightAxis.setEnabled(false);

        Legend l = mBcReportChart.getLegend();
        l.setEnabled(false);


    }

    private void setData() {
        mMyHandler.post(() -> {
            String fpString = "";
            JSONObject fpJsonObj = null;
            try {
                fpString = FileUtils.readJSONFile(FileUtils.json_filepath, mReport.getId());
            } catch (IOException e) {
                LogUtils.e(e);
                fpString = null;
                mProgressDialog.dismiss();
                mBcReportChart.setNoDataText(getString(R.string.string_load_fail));
                return;
            }


            //  第一阶段文件转换为JSON对象
            try {
                fpJsonObj = new JSONObject(fpString);
            } catch (JSONException e) {
                fpJsonObj = null;
                e.printStackTrace();
                mProgressDialog.dismiss();
                mBcReportChart.setNoDataText(getString(R.string.string_load_fail));
                return;
            }

            if (null == fpJsonObj) {
                LogUtils.d("Load file failed ! Please retry!");
                mProgressDialog.dismiss();
                mBcReportChart.setNoDataText(getString(R.string.string_load_fail));
                FileUtils.deleteFile(FileUtils.json_filepath, String.valueOf(mReport.getId()));
                if (null != mBcReportChart.getData()) {
                    mBcReportChart.getData().notifyDataChanged();
                    mBcReportChart.notifyDataSetChanged();
                }
                mBcReportChart.invalidate();
                return;
            }

            yVals1.clear();
//            colors.clear();

            JSONArray array = null;
            try {
                array = fpJsonObj.getJSONArray("floats");
            } catch (JSONException e) {
                LogUtils.e(e);
                mProgressDialog.dismiss();
                mBcReportChart.setNoDataText(getString(R.string.string_load_fail));
                return;
            }

            //设置报警线
            float high = SpUtils.getFloat(Extras.WARNING_HIGHEST_TEMP, 37.5F);
            float low = SpUtils.getFloat(Extras.WARNING_LOWEST_TEMP, 35.0F);
            try {
                high = (float) fpJsonObj.getDouble(Extras.RPT_ALERT_MAX);
            } catch (JSONException e) {
                e.printStackTrace();
                high = SpUtils.getFloat(Extras.WARNING_HIGHEST_TEMP, 37.5F);
            }

            try {
                low = (float) fpJsonObj.getDouble(Extras.RPT_ALERT_MIN);
            } catch (JSONException e) {
                e.printStackTrace();
                low = SpUtils.getFloat(Extras.WARNING_LOWEST_TEMP, 35.0F);
            }

            LimitLine limitLine;
            if (1 == SpUtils.getInt(Extras.TEMP_UNIT, Config.TEMP_UNIT_DEFAULT)) {
                limitLine = new LimitLine(37.2F, 37.2 + "℃");
            } else {
                limitLine = new LimitLine(FormatUtils.c2F(37.2F), FormatUtils.c2F(37.2F) + "℉");
            }

            limitLine.setTextSize(10f);
            limitLine.setLineWidth(2f);
            limitLine.enableDashedLine(10f, 10f, 0f);
            limitLine.setTextColor(ContextCompat.getColor(this, R.color.orange));
            limitLine.setLineColor(ContextCompat.getColor(this, R.color.orange));

            mLeftAxis.addLimitLine(limitLine);

            List<Float> list = new ArrayList<>();
            list.clear();
            Type listType = new TypeToken<ArrayList<Float>>() {
            }.getType();

            list = JSONUtils.getObj(array.toString(), listType, "yyyy-MM-dd");
            LogUtils.json(array.toString());
            LogUtils.d(list);

            if (null != list) {
                for (int i = 1; i <= list.size(); i++) {
                    //空保护必要
                    if (null != list.get(i - 1)) {
                        float val = list.get(i - 1);
                        if (1 == SpUtils.getInt(Extras.TEMP_UNIT, Config.TEMP_UNIT_DEFAULT)) {
                            yVals1.add(new BarEntry(i, val));
                        } else {
                            yVals1.add(new BarEntry(i, FormatUtils.c2F(val)));
                        }

                    }
                }
            }

            maxTemp = Collections.max(list);
            if (NumUtils.withinTempRange(maxTemp)) {

                if (1 == SpUtils.getInt(Extras.TEMP_UNIT, Config.TEMP_UNIT_DEFAULT)) {
                    mTvMaxTemp.setText(maxTemp + "");
                } else {
                    mTvMaxTemp.setText(FormatUtils.c2F(maxTemp) + "");
                }

            } else if (25F > maxTemp) {
                if (1 == SpUtils.getInt(Extras.TEMP_UNIT, Config.TEMP_UNIT_DEFAULT)) {
                    mTvMaxTemp.setText("< 25.00");

                } else {
                    mTvMaxTemp.setText("< 77.00");

                }
            } else if (45F < maxTemp) {
                if (1 == SpUtils.getInt(Extras.TEMP_UNIT, Config.TEMP_UNIT_DEFAULT)) {
                    mTvMaxTemp.setText("> 45.00");

                } else {
                    mTvMaxTemp.setText("> 113.00");

                }
            }

            mProgressDialog.dismiss();

            LineDataSet set1;
            if (mBcReportChart.getData() != null &&
                    mBcReportChart.getData().getDataSetCount() > 0) {
                set1 = (LineDataSet) mBcReportChart.getData().getDataSetByIndex(0);
                set1.setValues(yVals1);

                mBcReportChart.getData().notifyDataChanged();
                mBcReportChart.notifyDataSetChanged();
            } else {
                set1 = new LineDataSet(yVals1, "The year 2017");
//            set1.setColors(ColorTemplate.MATERIAL_COLORS);
                set1.setDrawFilled(true);
                set1.setDrawCircles(false);
                set1.disableDashedLine();
//                set1.enableDashedLine(10f, 5f, 0f);
                set1.enableDashedHighlightLine(10f, 5f, 0f);
                set1.setColor(Color.TRANSPARENT);
                set1.setCircleColor(Color.BLACK);
                set1.setLineWidth(0f);
//                set1.setCircleRadius(3f);
                set1.setDrawCircleHole(false);
                set1.setDrawValues(false);
//                set1.setValueTextSize(9f);
                set1.setDrawFilled(true);
                set1.setFormLineWidth(1f);
                set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
                set1.setFormSize(15.f);

//                ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
//                dataSets.add(set1);
                ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
                dataSets.add(set1); // add the datasets


                Drawable drawable = ContextCompat.getDrawable(this, R.drawable.line_chart);
                drawable.setAlpha(Config.CHART_ALPHA);
                set1.setFillDrawable(drawable);

                LineData data = new LineData(dataSets);
                data.setDrawValues(false);

                mBcReportChart.setData(data);

                if (maxTemp < 30) {
                    Description description = new Description();
                    description.setText(getString(R.string.string_out_of_range_temp));
                    mBcReportChart.setDescription(description);
                } else {
                    mBcReportChart.setDescription(null);
                }

                XYMarkerView mv = new XYMarkerView(this, mXAxisFormatter);
                mv.setStartTime(mReport.getStarttime());
                mv.setChartView(mBcReportChart); // For bounds control
                mBcReportChart.setMarker(mv); // Set the marker to the chart

                if (null != mBcReportChart.getData()) {
                    mBcReportChart.getData().notifyDataChanged();
                    mBcReportChart.notifyDataSetChanged();
                }
                mBcReportChart.invalidate();
//                mLineChart.invalidate();
            }

        });


    }

    @Override
    public void onValueSelected(Entry e, Highlight h) {

    }

    @Override
    public void onNothingSelected() {

    }

    private static class MyHandler extends Handler {
        private WeakReference<ReportBigChartActivity> activityWeakReference;

        public MyHandler(ReportBigChartActivity activity) {
            activityWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            ReportBigChartActivity activity = activityWeakReference.get();
            if (activity != null) {

            }
        }
    }
}
